//
// Created by user on 20-3-12.
//

#ifndef _LIB_H_
#define _LIB_H_

// 空指针
#define NULL 0

/**
 * 通过指定结构体的某个成员变量基地址，来计算出结构体变量的基地址，详情请看 Linux 的 containe_of
 */
#define containerOf(ptr, type, member)							\
({											\
	typeof(((type *)0)->member) * p = (ptr);					\
	(type *)((char *)p - (unsigned long)&(((type *)0)->member));		\
})

/**
 * 开中断
 */
#define sti() 		__asm__ __volatile__ ("sti	\n\t":::"memory")

#define cli()	 	__asm__ __volatile__ ("cli	\n\t":::"memory")
#define nop() 		__asm__ __volatile__ ("nop	\n\t")
#define mfence() 	__asm__ __volatile__ ("mfence	\n\t":::"memory")

#define hlt() 		__asm__ __volatile__ ("hlt	\n\t")
#define pause() 	__asm__ __volatile__ ("pause	\n\t")

/*===========================  结构体重名区  ===========================*/

typedef struct ListStruct List;

/*===========================  结构体定义区  ===========================*/

// 用来做双向链表
struct ListStruct {
    List * prev;
    List * next;
};

/*===========================  函数声明区  ===========================*/

/**
 * 初始化链表
 * @param list 要初始化的链表
 */
void listInit(List * list);

/**
 * 把新的 list 插入到当前 list 的前面
 * @param entry 当前的 list
 * @param new 新的 list
 */
void listAddToBefore(List * entry, List * new);

/**
 * 把新的 list 插入到当前 list 的后面
 * @param entry 当前的 list
 * @param new 新的 list
 */
void listAddToBehind(List *entry, List *new);

/**
 * 获取下一个链表
 * @param entry 当前链表
 * @return 下一个链表
 */
List * listNext(List * entry);

/**
 * 判断当前 list 是否为空
 * @param entry 要判断的 list 对象
 * @return 返回 0 和 1
 */
long listIsEmpty(List * entry);

/**
 * 删除当前 list
 * @param entry 要删除的list
 */
void listDel(List * entry);

/**
 * 向指定地址写入对应长度的重复字符的数据
 * @param Address 要写入的地址
 * @param C 要重复写入的字符
 * @param Count 指定的长度
 * @return
 */
void * memset(void * Address,unsigned char C,long Count);

/**
 * 内存复制函数
 * @param src 源地址
 * @param dest 目的地址
 * @param num 长度
 * @return
 */
void * memcpy(void * src, void * dest, long num);

extern int strlen(const char * String);

unsigned char io_in8(unsigned short port);

void io_out8(unsigned short port,unsigned char value);

unsigned int io_in32(unsigned short port);

void io_out32(unsigned short port, unsigned int value);

unsigned long rdmsr(unsigned long address);

void wrmsr(unsigned long address,unsigned long value);

/**
 * 获取 RFLAGS 标志寄存器的值
 * @return
 */
unsigned long getRFLAGS();

#endif //_LIB_H_